/**
 * Generali Solutions d'assurances - Tous droits réservés &copy; 2007 - 2010
 */
package fr.generali.accueilclient.contact.services.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Service;

import fr.generali.accueilclient.client.om.IAdresse;
import fr.generali.accueilclient.client.om.IContact;
import fr.generali.accueilclient.client.om.IContratsAdresse;
import fr.generali.accueilclient.client.om.IIdentifiantContact;
import fr.generali.accueilclient.client.om.builder.IdentifiantContactBuilder;
import fr.generali.accueilclient.commun.exception.AccueilClientBusinessException;
import fr.generali.accueilclient.commun.exception.AccueilClientModificationContactException;
import fr.generali.accueilclient.commun.exception.AccueilClientTechnicalException;
import fr.generali.accueilclient.contact.services.IContactService;
import fr.generali.refservcommuns.rce.communcontact.dossiercontact.DtoListeDossierMajAdresse;
import fr.generali.refservcommuns.rce.communcontact.dossiercontact.DtoListeDossierMajCourriel;
import fr.generali.refservcommuns.rce.communcontact.dossiercontact.DtoListeDossierMajPageWeb;
import fr.generali.refservcommuns.rce.communcontact.dossiercontact.DtoListeDossierMajTelephone;
import fr.generali.refservcommuns.rce.desactivation.desactivationservice.Desactivation;
import fr.generali.refservcommuns.rce.desactivation.services.IDesactivationWebService;
import fr.generali.refservcommuns.rce.gestioncontact.dtogestioncontact.DtoDossierP14;
import fr.generali.refservcommuns.rce.gestioncontact.dtogestioncontact.DtoListeDossierP14;
import fr.generali.refservcommuns.rce.gestioncontact.gestioncontactservice.GestionContact;
import fr.generali.refservcommuns.rce.gestioncontact.gestioncontactservice.GestionContactResponse;
import fr.generali.refservcommuns.rce.gestioncontact.services.IGestionContactWebService;
import fr.generali.refservcommuns.rce.majliens.MajLiensClientsAdrRib;
import fr.generali.refservcommuns.rce.majliens.services.MajLiensClientsAdrRibWebService;
import fr.generali.refservcommuns.rce.majliens.services.ResumeWSBusinessException;
import fr.generali.refservcommuns.rce.majliens.services.TechnicalFault;

/**
 * Implémentation de {@link IContactService}
 * 
 * @author selrhazala
 */
@Service
public class ContactService implements IContactService {

    /**
     * LOGGER
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(ContactService.class);

    /**
     * Service de gestion des contacts
     */
    @Autowired
    @Qualifier("P14")
    private IGestionContactWebService p14;

    /**
     * Service de désactivation contact et rib
     */
    @Autowired
    @Qualifier("P18")
    private IDesactivationWebService p18;

    /**
     * Service de propagation d'adresse
     */
    @Autowired
    @Qualifier("S22")
    private MajLiensClientsAdrRibWebService s22;

    /**
     * Assembler en entrée de P14
     */
    @Autowired
    @Qualifier("contactToGestionContactConverter")
    private Converter<IContact, GestionContact> contactToGestionContactConverter;

    /**
     * Assembler en entrée de P14
     */
    @Autowired
    @Qualifier("contactProToGestionContactConverter")
    private Converter<IContact, GestionContact> contactProToGestionContactConverter;

    /**
     * Assembler en entrée de P18
     */
    @Autowired
    @Qualifier("contactToDesactivationContactConverter")
    private Converter<IContact, Desactivation> contactToDesactivationContactConverter;

    /**
     * Assembler en entrée de S22
     */
    @Autowired
    @Qualifier("contratsAdresseToMajLiensClientsAdrRibConverter")
    private Converter<IContratsAdresse, MajLiensClientsAdrRib> contratsAdresseToMajLiensClientsAdrRibConverter;

    /**
     * {@inheritDoc}
     */
    public Map<IIdentifiantContact.TypeContact, IIdentifiantContact> modifierStopsCommunication(IContact contact)
                    throws AccueilClientBusinessException {
        GestionContactResponse gestionContactResponse = null;

        try {
            gestionContactResponse = p14.gestionContact(contactToGestionContactConverter.convert(contact));
        } catch (fr.generali.refservcommuns.rce.gestioncontact.services.TechnicalFault e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientTechnicalException(e.getMessage(), StringUtils.EMPTY, e);
        } catch (fr.generali.refservcommuns.rce.gestioncontact.services.WsRceBusinessException e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientModificationContactException(e.getMessage(), StringUtils.EMPTY, e);
        }

        if (gestionContactResponse != null) {
            DtoListeDossierP14 dtoListeDossierP14 = gestionContactResponse.getDtoListeDossierP14();
            if (dtoListeDossierP14 != null) {
                List<DtoDossierP14> listeDossierP14 = dtoListeDossierP14.getDossierP14();
                if (CollectionUtils.isNotEmpty(listeDossierP14)) {
                    return getIdentifiantContactResponse(listeDossierP14.get(0), contact);
                }
            }
        }

        return MapUtils.EMPTY_MAP;
    }

    /**
     * @param contact le contact
     * @return adresseRetour l'adresse retournée par le ws
     * @throws AccueilClientBusinessException exception fonctionnelle
     */
    public IAdresse creerAdresse(IContact contact) throws AccueilClientBusinessException {
        GestionContactResponse gestionContactResponse = null;

        try {
            gestionContactResponse = p14.gestionContact(contactToGestionContactConverter.convert(contact));
        } catch (fr.generali.refservcommuns.rce.gestioncontact.services.TechnicalFault e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientTechnicalException(e.getMessage(), StringUtils.EMPTY, e);
        } catch (fr.generali.refservcommuns.rce.gestioncontact.services.WsRceBusinessException e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientModificationContactException(e.getMessage(), StringUtils.EMPTY, e);
        }

        return completeAdresseFromResponse(gestionContactResponse, contact);
    }

    /**
     * @param gestionContactResponse la réponse du WS
     * @param contact le contact
     * @return adresseRetour l'adresse retournée par le ws
     */
    private IAdresse completeAdresseFromResponse(GestionContactResponse gestionContactResponse, IContact contact) {
        IAdresse adresseRetour = null;

        if (gestionContactResponse != null) {
            DtoListeDossierP14 dtoListeDossierP14 = gestionContactResponse.getDtoListeDossierP14();
            if (dtoListeDossierP14 != null) {
                List<DtoDossierP14> listeDossierP14 = dtoListeDossierP14.getDossierP14();
                if (CollectionUtils.isNotEmpty(listeDossierP14)) {
                    DtoDossierP14 dossierP14 = listeDossierP14.get(0);
                    if (dossierP14 != null && contact != null) {
                        adresseRetour = contact.getAdresse();
                        List<DtoListeDossierMajAdresse> listeAdressePostale = null;
                        if (CollectionUtils.isNotEmpty(dossierP14.getDossierContact().getAdresse())) {
                            listeAdressePostale = dossierP14.getDossierContact().getAdresse();
                            if (CollectionUtils.isNotEmpty(listeAdressePostale)) {
                                DtoListeDossierMajAdresse dossier = listeAdressePostale.get(0);
                                StringBuffer bfNumOrdre = new StringBuffer();

                                if (StringUtils.isNotEmpty(dossier.getDtoAdressePostale().getNumOrdre())
                                                && dossier.getDtoAdressePostale().getNumOrdre().length() < 2
                                                && Integer.valueOf(dossier.getDtoAdressePostale().getNumOrdre()) < 10) {
                                    bfNumOrdre.append("0");
                                }

                                bfNumOrdre.append(dossier.getDtoAdressePostale().getNumOrdre());

                                adresseRetour.setNumOrdre(bfNumOrdre.toString());
                                adresseRetour.setIdentifiant(dossier.getDtoAdressePostale().getIdentifiant());
                            }
                        }

                    }
                }
            }
        }

        return adresseRetour;
    }

    /**
     * {@inheritDoc}
     */
    public Map<IIdentifiantContact.TypeContact, IIdentifiantContact> gererContact(IContact contact)
                    throws AccueilClientBusinessException {
        GestionContactResponse gestionContactResponse = null;

        try {
            gestionContactResponse = p14.gestionContact(contactToGestionContactConverter.convert(contact));
        } catch (fr.generali.refservcommuns.rce.gestioncontact.services.TechnicalFault e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientTechnicalException(e.getMessage(), StringUtils.EMPTY, e);
        } catch (fr.generali.refservcommuns.rce.gestioncontact.services.WsRceBusinessException e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientBusinessException(e.getMessage(), e);
        }

        if (gestionContactResponse != null) {
            DtoListeDossierP14 dtoListeDossierP14 = gestionContactResponse.getDtoListeDossierP14();
            if (dtoListeDossierP14 != null) {
                List<DtoDossierP14> listeDossierP14 = dtoListeDossierP14.getDossierP14();
                if (CollectionUtils.isNotEmpty(listeDossierP14)) {
                    return getIdentifiantContactResponse(listeDossierP14.get(0), contact);
                }
            }
        }

        return MapUtils.EMPTY_MAP;
    }

    /**
     * {@inheritDoc}
     */
    public Map<IIdentifiantContact.TypeContact, IIdentifiantContact> gererContactPro(IContact contact)
                    throws AccueilClientBusinessException {
        GestionContactResponse gestionContactResponse = null;

        try {
            gestionContactResponse = p14.gestionContact(contactProToGestionContactConverter.convert(contact));

        } catch (fr.generali.refservcommuns.rce.gestioncontact.services.TechnicalFault e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientTechnicalException(e.getMessage(), StringUtils.EMPTY, e);
        } catch (fr.generali.refservcommuns.rce.gestioncontact.services.WsRceBusinessException e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientBusinessException(e.getMessage(), e);
        }

        if (gestionContactResponse != null) {
            DtoListeDossierP14 dtoListeDossierP14 = gestionContactResponse.getDtoListeDossierP14();
            if (dtoListeDossierP14 != null) {
                List<DtoDossierP14> listeDossierP14 = dtoListeDossierP14.getDossierP14();
                if (CollectionUtils.isNotEmpty(listeDossierP14)) {
                    return getIdentifiantContactResponse(listeDossierP14.get(0), contact);
                }
            }
        }

        return MapUtils.EMPTY_MAP;
    }

    /**
     * @param dossierP14 le dossier retourné par le WS
     * @param contact le contact
     * @return map IIdentifiantContact
     */
    private Map<IIdentifiantContact.TypeContact, IIdentifiantContact> getIdentifiantContactResponse(
                    DtoDossierP14 dossierP14, IContact contact) {

        Map<IIdentifiantContact.TypeContact, IIdentifiantContact> mapIdentifiantContact =
                        new HashMap<IIdentifiantContact.TypeContact, IIdentifiantContact>(0);

        if (dossierP14 != null) {

            IdentifiantContactBuilder identifiantContactBuilder = IdentifiantContactBuilder.identifiantContact();

            if (contact.getAdresse() != null) {
                List<DtoListeDossierMajAdresse> listeAdressePostale = null;
                if (CollectionUtils.isNotEmpty(dossierP14.getDossierContact().getAdresse())) {
                    listeAdressePostale = dossierP14.getDossierContact().getAdresse();
                    if (CollectionUtils.isNotEmpty(listeAdressePostale)) {
                        DtoListeDossierMajAdresse dossier = listeAdressePostale.get(0);

                        identifiantContactBuilder.buildIdentifiant(dossier.getDtoAdressePostale().getIdentifiant());
                        identifiantContactBuilder.buildNumeroOrdre(modifNumeroOrdreSur2Digits(dossier
                                        .getDtoAdressePostale().getNumOrdre()));
                        MapUtils.safeAddToMap(mapIdentifiantContact, IIdentifiantContact.TypeContact.ADRESSE,
                                        identifiantContactBuilder.build());
                    }
                }
            } else {
                if (contact.getTelephone() != null) {
                    List<DtoListeDossierMajTelephone> listeTelephone = null;
                    if (CollectionUtils.isNotEmpty(dossierP14.getDossierContact().getTelephone())) {
                        listeTelephone = dossierP14.getDossierContact().getTelephone();
                        if (CollectionUtils.isNotEmpty(listeTelephone)) {
                            DtoListeDossierMajTelephone dossier = listeTelephone.get(0);

                            identifiantContactBuilder.buildIdentifiant(dossier.getDtoTelephone().getNumero());
                            identifiantContactBuilder.buildNumeroOrdre(modifNumeroOrdreSur2Digits(dossier
                                            .getDtoTelephone().getNumOrdre()));
                            MapUtils.safeAddToMap(mapIdentifiantContact, IIdentifiantContact.TypeContact.TELEPHONE,
                                            identifiantContactBuilder.build());
                        }
                    }
                } else {
                    if (contact.getMail() != null) {
                        List<DtoListeDossierMajCourriel> listeCourriel = null;
                        if (CollectionUtils.isNotEmpty(dossierP14.getDossierContact().getCourriel())) {
                            listeCourriel = dossierP14.getDossierContact().getCourriel();
                            if (CollectionUtils.isNotEmpty(listeCourriel)) {
                                DtoListeDossierMajCourriel dossier = listeCourriel.get(0);

                                identifiantContactBuilder.buildIdentifiant(dossier.getDtoCourriel()
                                                .getAdresseCourriel());
                                identifiantContactBuilder.buildNumeroOrdre(modifNumeroOrdreSur2Digits(dossier
                                                .getDtoCourriel().getNumOrdre()));
                                MapUtils.safeAddToMap(mapIdentifiantContact, IIdentifiantContact.TypeContact.MAIL,
                                                identifiantContactBuilder.build());
                            }
                        }
                    } else {
                        if (contact.getSiteInternet() != null) {
                            List<DtoListeDossierMajPageWeb> listePageWeb = null;
                            if (CollectionUtils.isNotEmpty(dossierP14.getDossierContact().getPageWeb())) {
                                listePageWeb = dossierP14.getDossierContact().getPageWeb();
                                if (CollectionUtils.isNotEmpty(listePageWeb)) {
                                    DtoListeDossierMajPageWeb dossier = listePageWeb.get(0);

                                    identifiantContactBuilder.buildIdentifiant(dossier.getDtoPageWeb()
                                                    .getAdresseSiteWeb());
                                    identifiantContactBuilder.buildNumeroOrdre(modifNumeroOrdreSur2Digits(dossier
                                                    .getDtoPageWeb().getNumOrdre()));
                                    MapUtils.safeAddToMap(mapIdentifiantContact,
                                                    IIdentifiantContact.TypeContact.SITEINTERNET,
                                                    identifiantContactBuilder.build());

                                }
                            }
                        }
                    }
                }
            }
        }

        return mapIdentifiantContact;
    }

    /**
     * @param idRetour id retour
     * @return id retour sur deux digits
     */
    private String modifNumeroOrdreSur2Digits(String idRetour) {
        if (StringUtils.isNotEmpty(idRetour) && idRetour.length() < 2 && Integer.valueOf(idRetour) < 10) {
            StringBuffer bfIdRetour = new StringBuffer();
            bfIdRetour.append("0").append(idRetour);
            idRetour = bfIdRetour.toString();
        }
        return idRetour;
    }

    /**
     * {@inheritDoc}
     */
    public String propagerAdresse(IContratsAdresse contratsAdresse) throws AccueilClientBusinessException {
        try {
            s22.majLiensClientsAdrRib(contratsAdresseToMajLiensClientsAdrRibConverter.convert(contratsAdresse));
        } catch (ResumeWSBusinessException e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientModificationContactException(e.getMessage(), StringUtils.EMPTY, e);
        } catch (TechnicalFault e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientModificationContactException(e.getMessage(), StringUtils.EMPTY, e);
        }

        return StringUtils.EMPTY;
    }

    /**
     * {@inheritDoc}
     */
    public void desactiverContact(IContact contact) throws AccueilClientBusinessException {
        try {
            p18.desactivation(contactToDesactivationContactConverter.convert(contact));
        } catch (fr.generali.refservcommuns.rce.desactivation.services.TechnicalFault e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientTechnicalException(e.getMessage(), StringUtils.EMPTY, e);
        } catch (fr.generali.refservcommuns.rce.desactivation.services.WsRceBusinessException e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientModificationContactException(e.getMessage(), StringUtils.EMPTY, e);
        }
    }

}
